<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVS" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec2 a_Pin;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying vec2 v_Pin;
    void main(){
        vec4 posi = u_PvM4 * u_ModelM4 * a_Position;
        gl_Position = posi;
        v_Pin = a_Pin;
    }
  </script>
<script id="ColorFS" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Texture;
    uniform sampler2D u_Image;
    uniform float u_Set;
    varying vec2 v_Pin;
    void main(){
        float set = 10.0;
        vec2 uv = v_Pin;
        uv.x *= set;
        uv.y *= set;
        uv.x = floor(uv.x);
        uv.y = floor(uv.y);
        uv.x /= set;
        uv.y /= set;

        float depth = texture2D(u_Texture, uv).x;
        float curSet = smoothstep(0.0, 0.95, u_Set);
        if(depth > curSet){
            gl_FragColor = texture2D(u_Image, v_Pin);;
        }else{
            discard;
        }
        
    }
  </script>
<script type="module">
    import {
        Matrix4,
        Vector3,
        Color,
        OrthographicCamera,
        PerspectiveCamera,
        Spherical,
    } from "../js/three.module.js";
    import { CreateProgram, imgPromise } from "../js/Utils.js";
    import lib from "../js/ThreeLib.js";
    import CameraController from "../js/CameraController.js";
    import Poly from "../js/Poly4.js";
    import Control from "../js/Control.js";
    import Square from "../js/objs/Square.js";

    import Geo from "../js/Poly2/Geo.js";
    import Mat from "../js/Poly2/Mat.js";
    import Obj3D from "../js/Poly2/Obj3D.js";
    import Scene from "../js/Poly2/Scene.js";

    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl", { antialias: true });

    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); //去图片描边
    gl.enable(gl.DEPTH_TEST);
    //#endregion

    const scene = new Scene({ gl: gl });
    scene.addAxisProgram();
    scene.regProgram("color", {
        program: CreateProgram(
            gl,
            document.querySelector("#ColorVS").innerText,
            document.querySelector("#ColorFS").innerText
        ),
        attribs: ["a_Position", "a_Pin"],
        uniforms: ["u_PvM4", "u_ModelM4", "u_Color", "u_Texture", "u_Image", "u_Set"],
    });

    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const eye = new Vector3(0, 0, 3);
    const lookAt = new Vector3();

    const camera = new PerspectiveCamera(
        45,
        canvas.width / canvas.height,
        1,
        20
    );
    const cameraController = new CameraController({
        canvas,
        camera,
        pvMatrix: pvM4,
        eye,
        lookAt,
    });

    const axis = new Obj3D().createAxis("axis");
    scene.add(axis);

    const square = new Square(0.5);
    const [squareVertices, squareElements, squareNormals] = [
        square.vertices,
        square.elements,
        square.normals,
    ];

    const ground = [
        [-0.6, 0.5, -0.6, -0.5, 0.6, -0.5, 0.6, 0.5],
        [0, 1, 2, 0, 2, 3],
    ];

    //#region main

    let obj01 = create(ground[0], ground[1], [1, 1, 1, 1]);
    const image = new Image();
    image.src = '../Image/Image01.jpg';
    const image2 = new Image();
    image2.src = '../Image/Texture01.png';
    image2.onload = function () {

        obj01.addTexureNew(gl, {
            'u_Texture': {
                image: image2,
                WRAP_W: gl.CLAMP_TO_EDGE,
                WRAP_H: gl.CLAMP_TO_EDGE,
                MIN_FILTER: gl.LINEAR,
            },
            'u_Image': {
                image: image,
                WRAP_W: gl.CLAMP_TO_EDGE,
                WRAP_H: gl.CLAMP_TO_EDGE,
                MIN_FILTER: gl.LINEAR,
            }
        })
        scene.add(obj01);
    };


    //#endregion

    (function ani(time) {
        scene.setUniform('u_Set', { value: Math.sin(time / 2000) })
        // console.log(Math.sin(time / 2000))
        draw();
        requestAnimationFrame(ani);
    })(0);

    function create(vertices, elements = null, color = [Math.random(), Math.random(), Math.random(), 1]) {
        const geo = new Geo({
            data: {
                a_Position: { size: 2, array: new Float32Array(vertices) },
                a_Pin: { size: 2, array: new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]) },
            },
        });
        const mat = new Mat({
            program: "color",
            mode: ["LINES", "POINTS"],
            data: {
                u_PvM4: { type: "uniformMatrix4fv", value: pvM4.elements },
                u_ModelM4: { type: "uniformMatrix4fv", value: modelM4.elements },
                u_Set: { type: "uniform1f", value: 0 },
            },
        });
        if (elements != null) {
            geo.element = { array: new Uint16Array(elements) };
            mat.mode = ["TRIANGLES"];
        }
        return new Obj3D({ geo: geo, mat: mat });
    }

    function draw() {
        scene.setUniform("u_PvM4", { value: pvM4.elements });
        scene.draw();
    }
</script>

</html>